package cn.kinoko.controller.manga;

import cn.kinoko.common.aspect.annotation.CacheEvict;
import cn.kinoko.common.aspect.annotation.Cacheable;
import cn.kinoko.common.aspect.annotation.Lock;
import cn.kinoko.common.aspect.annotation.OwnershipCheck;
import cn.kinoko.common.base.model.BaseController;
import cn.kinoko.common.base.model.Result;
import cn.kinoko.common.base.validate.ValidGroup;
import cn.kinoko.common.constant.CacheKeyConstant;
import cn.kinoko.model.manga.entity.Manga;
import cn.kinoko.model.manga.req.*;
import cn.kinoko.model.manga.vo.MangaEpCookedVO;
import cn.kinoko.model.manga.vo.MangaEpRawVO;
import cn.kinoko.service.manga.MangaService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author kinoko
 */
@RestController
@RequestMapping("/manga/ep")
public class MangaEpController extends BaseController {

    @Resource
    private MangaService mangaService;

    // 保存章节
    @PostMapping("/save")
    @OwnershipCheck(bizId = "#req.mangaId", bizClass = Manga.class, isShared = true)
    @CacheEvict(key = CacheKeyConstant.MG_EP_LIST, params = "#req.mangaId")
    public Result<Object> epSave(@RequestBody @Validated MangaEpReq req) {
        return toAjax(mangaService.saveEp(req));
    }

    // 更新章节
    @PostMapping("/update")
    @CacheEvict(key = CacheKeyConstant.MG_EP_LIST, params = "#req.mangaId")
    @OwnershipCheck(bizId = "#req.mangaId", bizClass = Manga.class, isShared = true)
    public Result<Object> epUpdate(@RequestBody @Validated({ValidGroup.Update.class}) MangaEpReq req) {
        return toAjax(mangaService.epUpdate(req));
    }

    // 删除章节
    @PostMapping("/deleted")
    @CacheEvict(key = CacheKeyConstant.MG_EP_LIST, params = "#req.mangaId")
    @OwnershipCheck(bizId = "#req.mangaId", bizClass = Manga.class, isShared = true)
    public Result<Object> epDeleted(@RequestBody @Validated({ValidGroup.Delete.class}) MangaEpReq req) {
        return toAjax(mangaService.epDeleted(req));
    }

    // 章节重排序
    @PostMapping("/reSort")
    @CacheEvict(key = CacheKeyConstant.MG_EP_LIST, params = "#req.mangaId")
    @OwnershipCheck(bizId = "#req.mangaId", bizClass = Manga.class, isShared = true)
    public Result<Object> epReSort(@RequestBody @Validated MangaEpReSortReq req) {
        return toAjax(mangaService.epReSort(req));
    }

    // 设置章节是否展示
    @PostMapping("/available")
    @OwnershipCheck(bizId = "#req.mangaId", bizClass = Manga.class, isShared = true)
    public Result<Object> epAvailable(@RequestBody @Validated MangaEpAvailableReq req) {
        return toAjax(mangaService.epAvailable(req));
    }

    // 获取生肉列表
    @GetMapping("/rawList")
    @Cacheable(key = CacheKeyConstant.EP_RAW_IMG_LIST, params = "#epId")
    public Result<List<MangaEpRawVO>> rawList(@RequestParam Long epId) {
        return success(mangaService.rawList(epId));
    }

    // 获取熟肉列表
    @GetMapping("/cookedList")
    public Result<List<MangaEpCookedVO>> cookedList(@RequestParam Long epId) {
        return success(mangaService.cookedList(epId));
    }

    // 上传生肉
    @PostMapping("/uploadRawMg")
    @CacheEvict(key = CacheKeyConstant.EP_RAW_IMG_LIST, params = "#epId")
    @Lock(key = CacheKeyConstant.LOCK_EP_UPLOAD, params = "#epId", expire = 60)
    public Result<Object> uploadRawMg(@RequestParam("epId") Long epId,
                                      @RequestParam("files") MultipartFile[] files) throws Exception {
        return success(mangaService.uploadRawMg(epId, files));
    }

    // 重新上传生肉
    @PostMapping("/reUploadRawMg")
    @Lock(key = CacheKeyConstant.LOCK_EP_UPLOAD, params = "#epId", expire = 60)
    @CacheEvict(key = CacheKeyConstant.EP_RAW_IMG_LIST, params = "#epId")
    public Result<Object> reUploadRawMg(@RequestParam("epId") Long epId,
                                        @RequestParam("pageId") Long pageId,
                                        @RequestParam("files") MultipartFile file) throws Exception {
        return success(mangaService.reUploadRawMg(epId, pageId, file));
    }

    // 上传熟肉
    @PostMapping("/uploadCookedMg")
    @Lock(key = CacheKeyConstant.LOCK_EP_UPLOAD, params = "#epId", expire = 10, timeUnit = TimeUnit.MINUTES)
    @CacheEvict(key = CacheKeyConstant.EP_COOKED_IMG_LIST, params = "#epId")
    public Result<Object> uploadCookedMg(@RequestParam("epId") Long epId,
                                         @RequestParam("files") MultipartFile[] files) throws Exception {
        return success(mangaService.uploadCookedMg(epId, files));
    }

    // 重新上传熟肉
    @PostMapping("/reUploadCookedMg")
    @Lock(key = CacheKeyConstant.LOCK_EP_UPLOAD, params = "#epId", expire = 10, timeUnit = TimeUnit.MINUTES)
    @CacheEvict(key = CacheKeyConstant.EP_COOKED_IMG_LIST, params = "#epId")
    public Result<Object> reUploadCookedMg(@RequestParam("epId") Long epId,
                                           @RequestParam("pageId") Long pageId,
                                           @RequestParam("files") MultipartFile file) throws Exception {
        return success(mangaService.reUploadCookedMg(epId, pageId, file));
    }

    // 删除生肉
    @GetMapping("/deletedRaw")
    @CacheEvict(key = CacheKeyConstant.EP_RAW_IMG_LIST, params = "#epId")
    public Result<Object> deletedRaw(@RequestParam Long epId, @RequestParam Long pageId) {
        return success(mangaService.deletedRaw(epId, pageId));
    }

    // 清空生肉
    @GetMapping("/clearRaw")
    @CacheEvict(key = CacheKeyConstant.EP_RAW_IMG_LIST, params = "#epId")
    public Result<Object> clearRaw(@RequestParam Long epId) {
        return success(mangaService.clearRaw(epId));
    }

    // 删除熟肉
    @GetMapping("/deletedCooked")
    @CacheEvict(key = CacheKeyConstant.EP_COOKED_IMG_LIST, params = "#epId")
    public Result<Object> deletedCooked(@RequestParam Long epId, @RequestParam Long pageId) {
        return success(mangaService.deletedCooked(epId, pageId));
    }

    // 清空熟肉
    @GetMapping("/clearCooked")
    @CacheEvict(key = CacheKeyConstant.EP_COOKED_IMG_LIST, params = "#epId")
    public Result<Object> clearCooked(@RequestParam Long epId) {
        return success(mangaService.clearCooked(epId));
    }

    // 生肉页码重排序
    @PostMapping("/reSortRawList")
    @CacheEvict(key = CacheKeyConstant.EP_RAW_IMG_LIST, params = "#req.epId", waitTime = 1000)
    public Result<Object> reSortRawList(@RequestBody @Validated MangaPageReSortReq req) {
        return success(mangaService.reSortRawList(req));
    }

    // 熟肉页码重排序
    @PostMapping("/reSortCookedList")
    @CacheEvict(key = CacheKeyConstant.EP_COOKED_IMG_LIST, params = "#req.epId")
    public Result<Object> reSortCookedList(@RequestBody @Validated MangaPageReSortReq req) {
        return success(mangaService.reSortCookedList(req));
    }

    @PostMapping("/export")
    public Result<Object> export(@RequestBody MangaExportReq params) {
        return success(mangaService.export(params));
    }

    @GetMapping("/exportText")
    public void exportText(@RequestParam Long epId, HttpServletResponse response) {
        mangaService.exportText(epId, response);
    }

}
